﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;
using System.Windows.Forms;
using System.Threading;
using Mogre;

namespace MogreMicroscope
{
    public partial class Form1 : Form
    {
        protected MogreWindow mogreWin;
        TreeNode _currentNode = null;

        int _activeView = 0;
        int _oldView = 0;

        Vector3[] _activeViewPos = new Vector3[3];
        Vector3[] _oldViewPos = new Vector3[3];
        public Form1()
        {
            InitializeComponent();
            this.Disposed += new EventHandler(Form1_Disposed);

            mogreWin = new MogreWindow(new Point(100, 30), panelMogre.Handle, this.Handle);
            mogreWin.OnStatusChanged += new MogreWindow.StatusUpdateHandler(mogreWin_OnStatusChanged);
            mogreWin.InitMogre();
          
            //mogreWin.SetOrthoCamera();
            mogreWin.SetCameraPosition(Vector3.UNIT_SCALE, Vector3.ZERO, Vector3.NEGATIVE_UNIT_Z);
            _activeViewPos[0] = new Vector3();
            _activeViewPos[1] = new Vector3();
            _activeViewPos[2] = new Vector3();
            _oldViewPos[0] = new Vector3();
            _oldViewPos[1] = new Vector3();
            _oldViewPos[2] = new Vector3();
           

        }

        void mogreWin_OnStatusChanged(object sender, string data)
        {
            try
            {
                Invoke(new MethodInvoker(delegate { RefreshStatusDisplay(data); }));
            }
            catch
            {
                
            }
        }

        void RefreshStatusDisplay(string text)
        {
//            textBoxInfo.Text+= text;
        }

        void Form1_Disposed(object sender, EventArgs e)
        {
            mogreWin.Dispose();
        }

        private int GetCurrentGraphicObjectIndex()
        {
            if (textBoxCurrentSelection.Text != String.Empty)
            {
                return (int)((Primitive)textBoxCurrentSelection.Tag).Index;
            }
            return 0;
        }

        private void AddTreeNode(Primitive prim)
        {
            TreeNode tn = new TreeNode(prim.Name);
            tn.Tag = (Primitive)prim;
            treeView1.Nodes.Add(tn);
            _oldViewPos[_oldView] = mogreWin.GetCameraPosition();
            Vector3 pos = mogreWin.GetPrimitivePosition(prim.Index);
            _activeView = _oldView = 2;
            _activeViewPos[_activeView] = new Vector3(0, pos.y, pos.z + prim.BoundingBox.Size.z + 80);
            mogreWin.SetCameraPosition(_activeViewPos[_activeView], pos, Vector3.NEGATIVE_UNIT_Z);
            _oldViewPos[_oldView] = mogreWin.GetCameraPosition();
            mogreWin.PointCameraLevel();

            _oldViewPos[0] = new Vector3(0, pos.y+ prim.BoundingBox.Size.y + 80, pos.z);
            _oldViewPos[1] = new Vector3(pos.x + prim.BoundingBox.Size.x + 80, pos.y, pos.z);
                
        }

        #region ADD_PRIMITIVES

        private Vector3 ConvertPositionNumericTextBoxesDataToVector3()
        {
            return new Vector3(Convert.ToSingle(TextBoxXpos.Text), Convert.ToSingle(TextBoxYpos.Text), Convert.ToSingle(TextBoxZpos.Text)); 
        }
        private Vector3 ConvertOrientationNumericTextBoxesDataToVector3()
        {
            return new Vector3(Convert.ToSingle(numericTextBoxRotX.Text), Convert.ToSingle(numericTextBoxRotY.Text), Convert.ToSingle(numericTextBoxRotZ.Text)); 
        }
        
        private void buttonLoad_Click(object sender, EventArgs e)
        {
            float scale = Convert.ToSingle(textBoxScaleValue.Text);

            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                Vector3 Pos = ConvertPositionNumericTextBoxesDataToVector3();
                if (Pos == Vector3.ZERO)
                {
                    Pos.y = 80;
                }
                Primitive prim = mogreWin.LoadMesh(openFileDialog.FileName, Pos, Quaternion.IDENTITY, Vector3.UNIT_SCALE * GetScaleSetting());

                AddTreeNode(prim);


            }
        }

        
        private void buttonBox_Click(object sender, EventArgs e)
        {
            Vector3 Pos = ConvertPositionNumericTextBoxesDataToVector3();
            if (Pos == Vector3.ZERO)
            {
                Pos.y = 80;
            }
            Primitive prim = mogreWin.AddCollisionPrimitive("Box", CollisionType.Box, Pos, Quaternion.IDENTITY, Vector3.UNIT_SCALE * GetScaleSetting(), 100, true);
            AddTreeNode(prim);
           
        }

        private void buttonCylinder_Click(object sender, EventArgs e)
        {
            Vector3 Pos = ConvertPositionNumericTextBoxesDataToVector3();
            if (Pos == Vector3.ZERO)
            {
                Pos.y = 80;
            }
            Primitive prim = mogreWin.AddCollisionPrimitive("Cylinder", CollisionType.Cylinder, Pos, Quaternion.IDENTITY, new Vector3(1, 10, 0) * GetScaleSetting(), 100, true);
            AddTreeNode(prim);
        }

        private void buttonCapsule_Click(object sender, EventArgs e)
        {
            Vector3 Pos = ConvertPositionNumericTextBoxesDataToVector3();
            if (Pos == Vector3.ZERO)
            {
                Pos.y = 80;
            }
            Primitive prim = mogreWin.AddCollisionPrimitive("Capsule", CollisionType.Capsule, Pos, Quaternion.IDENTITY, new Vector3(1, 10, 0) * GetScaleSetting(), 100, true);
            AddTreeNode(prim);
        }

        private void buttonChamferCylinder_Click(object sender, EventArgs e)
        {
            Vector3 Pos = ConvertPositionNumericTextBoxesDataToVector3();
            if (Pos == Vector3.ZERO)
            {
                Pos.y = 80;
            }
            Primitive prim = mogreWin.AddCollisionPrimitive("ChamferCylinder", CollisionType.ChamferCylinder, Pos, Quaternion.IDENTITY, new Vector3(1, 10, 0) * GetScaleSetting(), 100, true);
            AddTreeNode(prim);
        }

        private void buttonCone_Click(object sender, EventArgs e)
        {
            Vector3 Pos = ConvertPositionNumericTextBoxesDataToVector3();
            if (Pos == Vector3.ZERO)
            {
                Pos.y = 80;
            }
            Primitive prim = mogreWin.AddCollisionPrimitive("Cone", CollisionType.Cone, Pos, Quaternion.IDENTITY, new Vector3(1, 10, 0) * GetScaleSetting(), 100, true);
 
            AddTreeNode(prim);
        }

        private void buttonEllipsoid_Click(object sender, EventArgs e)
        {
            Vector3 Pos = ConvertPositionNumericTextBoxesDataToVector3();
            if (Pos == Vector3.ZERO)
            {
                Pos.y = 80;
            }
            Primitive prim = mogreWin.AddCollisionPrimitive("Ellipsoid", CollisionType.Ellipsoid, Pos, Quaternion.IDENTITY, new Vector3(1, 10, 0) * GetScaleSetting(), 100, true);
            AddTreeNode(prim);
        }


        private void buttonCompoundCol_Click(object sender, EventArgs e)
        {
            Primitive prim = mogreWin.CreateComplexCollision("Compound", PrimitiveType.CompoundCol);
            Vector3 Pos = ConvertPositionNumericTextBoxesDataToVector3();
                if (Pos == Vector3.ZERO)
                {
                    Pos.y = 80;
                }
                prim.Position = Pos;
            //prim.Position = Vector3.UNIT_Y * 80f;
            AddTreeNode(prim);
        }

        private void buttonConvexHull_Click(object sender, EventArgs e)
        {
            Primitive prim = mogreWin.CreateComplexCollision("ConvexHull", PrimitiveType.ConvexHullCol);
            Vector3 Pos = ConvertPositionNumericTextBoxesDataToVector3();
            if (Pos == Vector3.ZERO)
            {
                Pos.y = 80;
            }
            prim.Position = Pos;
            AddTreeNode(prim);
        }

        private void buttonTreeCollision_Click(object sender, EventArgs e)
        {
            Primitive prim = mogreWin.CreateComplexCollision("Tree", PrimitiveType.TreeCol);
            Vector3 Pos = ConvertPositionNumericTextBoxesDataToVector3();
            if (Pos == Vector3.ZERO)
            {
                Pos.y = 80;
            }
            prim.Position = Pos;
            AddTreeNode(prim);
        }

        #endregion ADD_PRIMITIVES

        #region SCALE_ROTATE_TRANSLATE

        private float GetScaleSetting()
        {
            return Convert.ToSingle(textBoxScaleValue.Text);
        }
        
        enum Action : byte
        {
            x=1,
            y=2,
            z=4,
            c=8
        }

        Action Position = Action.x;
        Action Rotation = Action.x;
        Action actScale = Action.c;

        private void radioButtonXpos_CheckedChanged(object sender, EventArgs e)
        {
            Position = Action.x;
        }

        private void radioButtonYpos_CheckedChanged(object sender, EventArgs e)
        {
            Position = Action.y;
        }

        private void radioButtonZpos_CheckedChanged(object sender, EventArgs e)
        {
            Position = Action.z;
        }

        private void radioButtonAllPos_CheckedChanged(object sender, EventArgs e)
        {
            Position = Action.c;
        }

        delegate void actOn(object sender, EventArgs e);



        private void buttonInc_Click(object sender, EventArgs e)
        {
            timerMultiClick.Tag = null;
            float val = Convert.ToSingle(textBoxPos.Text);
            actOn actt = new actOn(buttonInc_Click);
            timerMultiClick.Tag = actt;

            ChangePosition(val);

            if (sender.GetType() == typeof(Button))
            {
                if (timerMultiClick.Enabled)
                {
                    timerMultiClick.Stop();
                }
                else
                {
                    timerMultiClick.Start();
                }

            }
           
            
        }

        private void buttonDec_Click(object sender, EventArgs e)
        {
            timerMultiClick.Tag = null;
            float val = Convert.ToSingle(textBoxPos.Text);
            actOn actt = new actOn(buttonDec_Click);
            timerMultiClick.Tag = actt;
           
            ChangePosition(-val);
            if (sender.GetType() == typeof(Button))
            {
                if (timerMultiClick.Enabled)
                {
                    timerMultiClick.Stop();
                }
                else
                {
                    timerMultiClick.Start();
                }

            }
        }

        private void buttonIncSing_Click(object sender, EventArgs e)
        {
            float val = Convert.ToSingle(textBoxPos.Text);
            ChangePosition(val);
        }

        private void buttonDecSing_Click(object sender, EventArgs e)
        {
            float val = Convert.ToSingle(textBoxPos.Text);
            ChangePosition(-val);
        }


        private void ChangePosition(float val)
        {
            Quaternion orient = mogreWin.GetPrimitiveOrientation(GetCurrentGraphicObjectIndex());
            Vector3 pos = mogreWin.GetPrimitivePosition(GetCurrentGraphicObjectIndex());
            switch (Position)
            {
                case Action.x:
                    pos.x += val;
                    break;
                case Action.y:
                    pos.y += val;
                    break;
                case Action.z:
                    pos.z += val;
                    break;
                default:
                    pos += val;
                    break;
            }
            mogreWin.SetPrimitivePositionOrientation(GetCurrentGraphicObjectIndex(), pos, orient);
            TextBoxXpos.Text = mogreWin.GetPrimitivePosition(GetCurrentGraphicObjectIndex()).x.ToString();
            TextBoxYpos.Text = mogreWin.GetPrimitivePosition(GetCurrentGraphicObjectIndex()).y.ToString();
            TextBoxZpos.Text = mogreWin.GetPrimitivePosition(GetCurrentGraphicObjectIndex()).z.ToString();
        }


        private void ChangeRotation(float val)
        {
            Quaternion orient = mogreWin.GetPrimitiveOrientation(GetCurrentGraphicObjectIndex());
            Vector3 pos = mogreWin.GetPrimitivePosition(GetCurrentGraphicObjectIndex());
            switch (Rotation)
            {
                case Action.x:
                    orient = mogreWin.RotateAxis(orient, Vector3.UNIT_X, new Radian(new Degree(val)).ValueRadians);
                    break;
                case Action.y:
                    orient = mogreWin.RotateAxis(orient, Vector3.UNIT_Y, new Radian(new Degree(val)).ValueRadians);
                    break;
                case Action.z:
                    orient = mogreWin.RotateAxis(orient, Vector3.UNIT_Z, new Radian(new Degree(val)).ValueRadians);
                    break;
                default:
                    orient = Quaternion.IDENTITY;
                    break;
            }
            mogreWin.SetPrimitivePositionOrientation(GetCurrentGraphicObjectIndex(), pos, orient);
            orient = mogreWin.GetPrimitiveOrientation(GetCurrentGraphicObjectIndex());
            numericTextBoxRotX.Text = orient.Pitch.ValueDegrees.ToString();
            numericTextBoxRotY.Text = orient.Yaw.ValueDegrees.ToString();
            numericTextBoxRotZ.Text = orient.Roll.ValueDegrees.ToString();
        }

        private void ChangeScale(float val)
        {
            Vector3 scale = mogreWin.GetPrimitiveScale(GetCurrentGraphicObjectIndex());
            if (scale.Length > 0 || val > 0)
            {
                switch (actScale)
                {
                    case Action.x:
                        scale.x += val;

                        break;
                    case Action.y:
                        scale.y += val;

                        break;
                    case Action.z:
                        scale.z += val;

                        break;
                    default:
                        scale += val;
                        break;
                }
                mogreWin.SetPrimitiveScale(GetCurrentGraphicObjectIndex(), scale);
            }
        }

        private void radioButtonXrot_CheckedChanged(object sender, EventArgs e)
        {
            Rotation = Action.x;
        }

        private void radioButtonYrot_CheckedChanged(object sender, EventArgs e)
        {
            Rotation = Action.y;
        }

        private void radioButtonZrot_CheckedChanged(object sender, EventArgs e)
        {
            Rotation = Action.z;
        }

        private void radioButtonAllrot_CheckedChanged(object sender, EventArgs e)
        {
            Rotation = Action.c;
            ChangeRotation(GetCurrentGraphicObjectIndex());
        }

        private void buttonRotInc_Click(object sender, EventArgs e)
        {

            timerMultiClick.Tag = null;
            float val = Convert.ToSingle(textBoxRotValue.Text);
            actOn actt = new actOn(buttonRotInc_Click);
            timerMultiClick.Tag = actt;

            ChangeRotation(val);
            if (sender.GetType() == typeof(Button))
            {
                if (timerMultiClick.Enabled)
                {
                    timerMultiClick.Stop();
                }
                else
                {
                    timerMultiClick.Start();
                }

            }
        }

        private void buttonRotDec_Click(object sender, EventArgs e)
        {
            timerMultiClick.Tag = null;
            float val = Convert.ToSingle(textBoxRotValue.Text);
            actOn actt = new actOn(buttonRotDec_Click);
            timerMultiClick.Tag = actt;

            ChangeRotation(-val);
            if (sender.GetType() == typeof(Button))
            {
                if (timerMultiClick.Enabled)
                {
                    timerMultiClick.Stop();
                }
                else
                {
                    timerMultiClick.Start();
                }

            }
        }


        private void buttonRotIncSing_Click(object sender, EventArgs e)
        {
            float val = Convert.ToSingle(textBoxRotValue.Text);
            ChangeRotation(val);
        }

        private void buttonRotDecSing_Click(object sender, EventArgs e)
        {
            float val = Convert.ToSingle(textBoxRotValue.Text);
            ChangeRotation(-val);
        }

        

        private void radioButtonXscale_CheckedChanged(object sender, EventArgs e)
        {
            actScale = Action.x;
        }

        private void radioButtonYscale_CheckedChanged(object sender, EventArgs e)
        {
            actScale = Action.y;
        }

        private void radioButtonZscale_CheckedChanged(object sender, EventArgs e)
        {
            actScale = Action.z;
        }

        private void radioButtonAllscale_CheckedChanged(object sender, EventArgs e)
        {
            actScale = Action.c;
        }

        private void buttonIncScale_Click(object sender, EventArgs e)
        {
            
           
            timerMultiClick.Tag = null;
            float val = Convert.ToSingle(textBoxScaleValue.Text);
            actOn actt = new actOn(buttonIncScale_Click);
            timerMultiClick.Tag = actt;

            ChangeScale(val);
            if (sender.GetType() == typeof(Button))
            {
                if (timerMultiClick.Enabled)
                {
                    timerMultiClick.Stop();
                }
                else
                {
                    timerMultiClick.Start();
                }

            }


        }

        private void buttonDecScale_Click(object sender, EventArgs e)
        {
            timerMultiClick.Tag = null;
            float val = Convert.ToSingle(textBoxScaleValue.Text);
            actOn actt = new actOn(buttonDecScale_Click);
            timerMultiClick.Tag = actt;

            ChangeScale(-val);
            if (sender.GetType() == typeof(Button))
            {
                if (timerMultiClick.Enabled)
                {
                    timerMultiClick.Stop();
                }
                else
                {
                    timerMultiClick.Start();
                }

            }
        }

        private void buttonIncScaleSing_Click(object sender, EventArgs e)
        {
            float val = Convert.ToSingle(textBoxScaleValue.Text);
            ChangeScale(val);
        }

        private void buttonDecScaleSing_Click(object sender, EventArgs e)
        {
            float val = Convert.ToSingle(textBoxScaleValue.Text);
            ChangeScale(-val);
        }

        private void button_MouseLeave(object sender, EventArgs e)
        {
            timerMultiClick.Stop();
        }

        #endregion SCALE_ROTATE_TRANSLATE

        private void panelMogre_MouseEnter(object sender, EventArgs e)
        {
            mogreWin.IsMouseInRenderPanel = true;
        }

        private void panelMogre_MouseLeave(object sender, EventArgs e)
        {
            mogreWin.IsMouseInRenderPanel = false;
        }

        private void panelMogre_MouseClick(object sender, MouseEventArgs e)
        {
            if (mogreWin.ClickedOnPrimitive(e.X, e.Y))
            {

            }

        }

        private void checkBoxGravity_CheckedChanged(object sender, EventArgs e)
        {
            mogreWin.IsGravity = checkBoxGravity.Checked;
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            mogreWin.SetPrimitiveGravity(GetCurrentGraphicObjectIndex(), !checkBox1.Checked);
        }

        #region TREEVIEW_HANDLING

        private void treeView1_MouseClick(object sender, MouseEventArgs e)
        {

        }
        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            _currentNode = treeView1.SelectedNode;
            if (_currentNode != null)
            {
                textBoxCurrentSelection.Text = _currentNode.Text;
                textBoxCurrentSelection.Tag = _currentNode.Tag;
                mogreWin.SetPrimitiveGravity(GetCurrentGraphicObjectIndex(), !checkBox1.Checked);
            }
            else
            {
                textBoxCurrentSelection.Text = "";
                textBoxCurrentSelection.Tag = null;
            }
        }

        protected bool IsSimpleCollisonType(PrimitiveType type)
        {
            if (type == PrimitiveType.BoxCol ||
                type == PrimitiveType.CapsuleCol ||
                type == PrimitiveType.ChamferCylinderCol ||
                type == PrimitiveType.ConeCol ||
                type == PrimitiveType.CylinderCol ||
                type == PrimitiveType.EllipsoidCol)
            {
                return true;
            }

            return false;

        }

        protected bool IsComplexCollisonType(PrimitiveType type)
        {
            if (type == PrimitiveType.CompoundCol ||
                type == PrimitiveType.ConvexHullCol ||
                type == PrimitiveType.TreeCol)
            {
                return true;
            }

            return false;

        }

        private void treeView1_DragDrop(object sender, DragEventArgs e)
        {
            TreeNode NewNode;

            if (e.Data.GetDataPresent("System.Windows.Forms.TreeNode", false))
            {
                Point pt = ((TreeView)sender).PointToClient(new Point(e.X, e.Y));
                TreeNode DestinationNode = ((TreeView)sender).GetNodeAt(pt);
                NewNode = (TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode");
                bool move = false;
                if (DestinationNode != NewNode)
                {
                    // Col prim on to Compound cols
                    // Node on to Compound cols
                    // Node on to ConvexHull
                    // Node on to Tree
                   
                    switch ((((Primitive)DestinationNode.Tag).PrimitiveClass))
                    {
                        case PrimitiveType.CompoundCol:
                            if (((Primitive)NewNode.Tag).PrimitiveClass == PrimitiveType.Node || IsSimpleCollisonType(((Primitive)NewNode.Tag).PrimitiveClass))
                            {
                                move = true;
                            }
                            break;
                        case PrimitiveType.ConvexHullCol:
                            if (((Primitive)NewNode.Tag).PrimitiveClass == PrimitiveType.Node)
                            {
                                move = true;
                            }
                            break;
                        case PrimitiveType.TreeCol:
                            if (((Primitive)NewNode.Tag).PrimitiveClass == PrimitiveType.Node)
                            {
                                move = true;
                            }
                            break;
                    }
                }


                if (move == true)
                {
                    if (((Primitive)DestinationNode.Tag).PrimitiveClass == PrimitiveType.ConvexHullCol)
                    {
                        mogreWin.BuildConvexHull(((Primitive)DestinationNode.Tag), ((Primitive)NewNode.Tag).Node);
                    }
                    else
                        if (((Primitive)DestinationNode.Tag).PrimitiveClass == PrimitiveType.TreeCol)
                        {
                            mogreWin.BuildTree(((Primitive)DestinationNode.Tag), ((Primitive)NewNode.Tag).Node);
                        }
                    DestinationNode.Nodes.Add((TreeNode)NewNode.Clone());
                    DestinationNode.Expand();
                    //Remove Original Node
                    NewNode.Remove();
                   
                }
                
            }
        }

        private void treeView1_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Move;
        }

        private void treeView1_DragOver(object sender, DragEventArgs e)
        {
            Point pt = ((TreeView)sender).PointToClient(new Point(e.X, e.Y));
            treeView1.SelectedNode = ((TreeView)sender).GetNodeAt(pt);
        }

        private void treeView1_ItemDrag(object sender, ItemDragEventArgs e)
        {
            TreeNode dragging = e.Item as TreeNode;
            if (IsComplexCollisonType(((Primitive)dragging.Tag).PrimitiveClass) == false)
            {
                DoDragDrop(e.Item, DragDropEffects.Move);
            }
            else
            {
                treeView1.SelectedNode = dragging;
            }
            //Point pt = ((TreeView)sender).PointToClient(new Point(e.X, e.Y));
            //treeView1.SelectedNode = ((TreeView)sender).GetNodeAt(pt);
            //

            
        }

        private void treeView1_DoubleClick(object sender, EventArgs e)
        {
            mogreWin.PointCameraAt( ((Primitive)treeView1.SelectedNode.Tag).Position);
        }

        private void treeView1_MouseUp(object sender, MouseEventArgs e)
        {
            // Show menu only if the right mouse button is clicked.
            if (e.Button == MouseButtons.Right)
            {

                // Point where the mouse is clicked.
                Point p = new Point(e.X, e.Y);

                // Get the node that the user has clicked.
                TreeNode node = treeView1.GetNodeAt(p);
                if (node != null)
                {
                    mnuBuild.Enabled = false;
                    mnuExport.Enabled = false;
                    deconstructCompoundCollisionToolStripMenuItem.Enabled = false;
                    //importCollisionToolStripMenuItem.Enabled = false;

                    switch ((((Primitive)node.Tag).PrimitiveClass))
                    {
                        case PrimitiveType.CompoundCol:
                            mnuBuild.Enabled = true;
                            mnuExport.Enabled = true;
                            deconstructCompoundCollisionToolStripMenuItem.Enabled = true;
                            importCollisionToolStripMenuItem.Enabled = true;
                            break;
                        case PrimitiveType.ConvexHullCol:
                            mnuExport.Enabled = true;
                            importCollisionToolStripMenuItem.Enabled = true;
                            break;
                        case PrimitiveType.TreeCol:
                            mnuExport.Enabled = true;
                            importCollisionToolStripMenuItem.Enabled = true;
                            break;
                        case PrimitiveType.Node:
                            mnuBuild.Enabled = true;
                            importCollisionToolStripMenuItem.Enabled = true;
                            break;
                    }
                    treeView1.SelectedNode = node;

                    contextMenuStripTreeView.Show(treeView1, p);
                }
                else
                {
                    mnuBuild.Enabled = false;
                    mnuExport.Enabled = false;
                    deconstructCompoundCollisionToolStripMenuItem.Enabled = false;
                    importCollisionToolStripMenuItem.Enabled = true;
                    mnuDelete.Enabled = false;
                    renameToolStripMenuItem.Enabled = false;
                    cloneToolStripMenuItem.Enabled = false;

                    contextMenuStripTreeView.Show(treeView1, p);

                }
            }
        }

        #endregion TREEVIEW_HANDLING

        #region VIEW_BUTTONS
        private void buttonViewTop_Click(object sender, EventArgs e)
        {
            _oldViewPos[_oldView] = mogreWin.GetCameraPosition();
            Vector3 pos = mogreWin.GetPrimitivePosition(GetCurrentGraphicObjectIndex());
            _activeView = _oldView = 0;
            _activeViewPos[_activeView] = _oldViewPos[_oldView];
            mogreWin.SetCameraPosition(_activeViewPos[_activeView]);
            _oldViewPos[_oldView] = mogreWin.GetCameraPosition();
            mogreWin.PointCameraDown();

        }

        private void buttonViewSide_Click(object sender, EventArgs e)
        {
            _oldViewPos[_oldView] = mogreWin.GetCameraPosition();
            Vector3 pos = mogreWin.GetPrimitivePosition(GetCurrentGraphicObjectIndex());
            _activeView = _oldView = 1;
            _activeViewPos[_activeView] = _oldViewPos[_oldView];
            mogreWin.SetCameraPosition(_activeViewPos[_activeView], pos, Vector3.NEGATIVE_UNIT_X);
            _oldViewPos[_oldView] = mogreWin.GetCameraPosition();
            mogreWin.PointCameraLevel();
        }

        private void buttonViewFront_Click(object sender, EventArgs e)
        {
            _oldViewPos[_oldView] = mogreWin.GetCameraPosition();
            Vector3 pos = mogreWin.GetPrimitivePosition(GetCurrentGraphicObjectIndex());
            _activeView = _oldView = 2;
            _activeViewPos[_activeView] = _oldViewPos[_oldView];
            mogreWin.SetCameraPosition(_activeViewPos[_activeView], pos, Vector3.NEGATIVE_UNIT_Z);
            _oldViewPos[_oldView] = mogreWin.GetCameraPosition();
            mogreWin.PointCameraLevel();
        }

        #endregion VIEW_BUTTONS

        #region CONTEXT_MENU_RELATED
        private void mnuBuild_Click(object sender, EventArgs e)
        {

            Primitive MogreNode = null;
            Primitive NewtonNode = null;

            if (((Primitive)treeView1.SelectedNode.Tag).IsNode() == false)
            {
                NewtonNode = ((Primitive)treeView1.SelectedNode.Tag);
                NewtonNode.BodyCols.Clear();
                foreach (TreeNode node in treeView1.SelectedNode.Nodes)
                {
                    if (((Primitive)node.Tag).IsNode() == true)
                    {
                        MogreNode = ((Primitive)node.Tag);
                        NewtonNode.BodyCols.Add(MogreNode);
                    }
                    else
                    {
                        NewtonNode.BodyCols.Add((Primitive)node.Tag);
                    }
                    //mogreWin.CreateCompoundObject(
                }
                Primitive[] primCol = NewtonNode.BodyCols.ToArray();
                mogreWin.BuildCompound(NewtonNode, ref primCol, MogreNode.Node);

                foreach (TreeNode node in treeView1.SelectedNode.Nodes)
                {
                    if (((Primitive)node.Tag).IsNode() == false)
                    {
                       mogreWin.RemovePrimitive(((Primitive)node.Tag).Index);

                    }
                }
                treeView1.SelectedNode.Nodes.Clear();
                NewtonNode.Position = MogreNode.Position;
            }
            else
            {
                Primitive prim = mogreWin.CreateCompoundObjectFromSceneNode(((Primitive)treeView1.SelectedNode.Tag).Node);
                AddTreeNode(prim);
                treeView1.Nodes.Remove(treeView1.SelectedNode);
                textBoxCurrentSelection.Tag = null;
                textBoxCurrentSelection.Text = "";
            }
        }

        private void deconstructCompoundCollisionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Primitive prim = (Primitive)treeView1.SelectedNode.Tag;

            Primitive[] prims = mogreWin.DeconstructCompoundFromPrimitive(prim);
            if (prims != null)
            {
                foreach (Primitive item in prims)
                {
                    AddTreeNode(item);

                }
                treeView1.Nodes.Remove(treeView1.SelectedNode);
                textBoxCurrentSelection.Tag = null;
                textBoxCurrentSelection.Text = "";
            }
        }

        private void mnuExport_Click(object sender, EventArgs e)
        {
            if(saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                mogreWin.ExportCollision((Primitive)treeView1.SelectedNode.Tag, saveFileDialog1.FileName);
            }
         
        }

        private void importCollisionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                Primitive prim = new Primitive();
                mogreWin.ImportCollision(ref prim, openFileDialog1.FileName);
                if (prim != null)
                {
                    if (prim.PrimitiveClass != PrimitiveType.Node)
                    {
                        mogreWin.RebuildBodies(prim);
                        AddTreeNode(prim);
                    }
                    foreach (Primitive item in prim.BodyCols)
                    {
                        if (item.PrimitiveClass != PrimitiveType.Node)
                        {
                            mogreWin.RebuildBodies(item);
                            AddTreeNode(item);
                        }

                    }
                }
                
            }
        }

        private void mnuDelete_Click(object sender, EventArgs e)
        {
            if (IsComplexCollisonType((((Primitive)treeView1.SelectedNode.Tag).PrimitiveClass)) == false)
            {
                mogreWin.RemovePrimitive(((Primitive)treeView1.SelectedNode.Tag).Index);
                treeView1.Nodes.Remove(treeView1.SelectedNode);
                textBoxCurrentSelection.Tag = null;
                textBoxCurrentSelection.Text = "";
            }
            else
            {
                mogreWin.RemoveComplexCollisionPrimitive(((Primitive)treeView1.SelectedNode.Tag).Index);
            }
            
        }

        

        private void cloneToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Primitive prim1 = mogreWin.AddClone(((Primitive)treeView1.SelectedNode.Tag));

            //Primitive prim = mogreWin.AddCollisionPrimitive("Box", CollisionType.Box, Vector3.UNIT_Y * 80f, Quaternion.IDENTITY, Vector3.UNIT_SCALE * GetScaleSetting(), 100, true);
            AddTreeNode(prim1);

        }

        #region RENAME
        private void renameToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //

           // treeView1.SelectedNode = mySelectedNode;
            treeView1.LabelEdit = true;
            treeView1.SelectedNode.BeginEdit();
            

            
            //treeView1.SelectedNode.Text = "Renamed";
            
        }

        private void treeView1_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
        {
            if (e.Label != null)
            {
                if (e.Label.Length > 0)
                {
                    if (e.Label.IndexOfAny(new char[] { '@', '.', ',', '!' }) == -1)
                    {
                        // Stop editing without canceling the label change.
                        e.Node.EndEdit(false);
                    }
                    else
                    {
                        /* Cancel the label edit action, inform the user, and 
                           place the node in edit mode again. */
                        e.CancelEdit = true;
                        MessageBox.Show("Invalid tree node label.\n" +
                           "The invalid characters are: '@','.', ',', '!'",
                           "Node Label Edit");
                        e.Node.BeginEdit();
                    }
                }
                else
                {
                    /* Cancel the label edit action, inform the user, and 
                       place the node in edit mode again. */
                    e.CancelEdit = true;
                    MessageBox.Show("Invalid tree node label.\nThe label cannot be blank",
                       "Node Label Edit");
                    e.Node.BeginEdit();
                }
                treeView1.LabelEdit = false;
                mogreWin.RenamePrimitive(((Primitive)treeView1.SelectedNode.Tag).Index, e.Label);
                textBoxCurrentSelection.Text = e.Label;
            }


            

        }
        #endregion RENAME

        private void timerMultiClick_Tick(object sender, EventArgs e)
        {
           // (actOn)(this.Tag);
            System.Windows.Forms.Timer tim = sender as System.Windows.Forms.Timer;
            Console.WriteLine(tim.Tag);
            actOn oo = (actOn)tim.Tag;
            oo(sender,e);
        }

        #endregion CONTEXT_MENU_RELATED

    }
}
